package com.ericsson.middleware.PermanentPooling;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.ericsson.middleware.PropertiesProvider;
import com.ericsson.middleware.ContextBroker.ContextBrokerClient;
import com.ericsson.middleware.ContextBroker.UpdateContext;
import com.ericsson.middleware.ContextBroker.UpdateContextResponse;
import com.ericsson.middleware.dao.LampDao;
import com.ericsson.middleware.entities.LampState;
import com.ericsson.middleware.slsp.Record;
import com.ericsson.middleware.slsp.RecordList;
import com.ericsson.middleware.slsp.SmartLightningClient;
import com.ericsson.middleware.utils.JsonUtil;

@Component
public class LampsAsyncWorker implements LampsWorker {

	private final static Logger LOGGER = Logger
			.getLogger(LampsAsyncWorker.class.getName());

	private String updateAction = PropertiesProvider.getUPDATE_ACTION_UPDATE();
	
	@Async
	public void work(int i) {

		LOGGER.log(Level.INFO, "Lamps Poller...");

		// polling GET/lamps
		SmartLightningClient lightningClient = new SmartLightningClient();
		RecordList lamps = lightningClient.getLamps();

		// check all lamps state
		for (Record temp : lamps.getRecord()) {
			LampDao lampService = new LampDao();
			String builtId = temp.getBranchName() + "_"
					+ temp.getLuminaireName();

			LampState fromDB = null;
			try {
				fromDB = lampService.findById(builtId);
			} catch (Exception e) {
				LOGGER.log(Level.SEVERE, "failed to find " + builtId + " : " + e.getMessage());
				fromDB = null;
			}			

			if (fromDB == null || !fromDB.getPWM().equals(temp.getPWM()) 
					|| !fromDB.getSerialID().equals(temp.getSerialID())) {

				LOGGER.log(
						Level.INFO, "Will update " + builtId);

				LampState updateLamp = new LampState(temp.getBranchName() + "_"
						+ temp.getLuminaireName(), temp.getSerialID(),
						temp.getCurrentIntensity(), temp.getPWM(), temp.getTimestamp(), temp.getLat(), temp.getLong());

				// if there is no entry on database, insert. 
				try {
					if (fromDB == null) {
						lampService.insert(updateLamp);
						updateAction = PropertiesProvider.getUPDATE_ACTION_APPEND();
					}
					else {
						lampService.update(updateLamp);
						updateAction = PropertiesProvider.getUPDATE_ACTION_UPDATE();
					}
				} catch (Exception e) {
					LOGGER.log(Level.SEVERE, "failed to update database" + updateLamp.getId());
					updateAction = "UPDATE";
				}

				try {
					ContextBrokerClient cbClient = new ContextBrokerClient();
					UpdateContext updateContext = cbClient.buildUpdateContext(PropertiesProvider.getLAMPS_TYPE(), updateAction, temp);
					LOGGER.log(Level.INFO, "Update request: " + JsonUtil.toJson(updateContext));					
					UpdateContextResponse response = cbClient.sendUpdateContextWithReAttempts(JsonUtil.toJson(updateContext), Integer.parseInt(PropertiesProvider.getUPDATE_REATTEMPTS()));
					LOGGER.log(Level.INFO, "Update response: " + JsonUtil.toJson(response));					

				} catch (Exception e) {
					LOGGER.log(Level.SEVERE, "failed to update Context Broker" + updateLamp.getId());
				}

			}
		}

	}
}